﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
//using System.Drawing;
using Microsoft.Kinect;
using System.Diagnostics;
using System.Windows.Threading;

namespace GraduateDesign
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class GameWindow : Window
    {
        DispatcherTimer timer = new DispatcherTimer();
        private Brush[] brushes;
        private KinectSensor kinectDevice;
        private Skeleton[] frameSkeletons;
        private Random rand = new Random();
      //  private int lostNum = 0;
        public GameWindow()
        {
            InitializeComponent();
            KinectSensor.KinectSensors.StatusChanged += KinectSensors_StatusChanged;
            this.KinectDevice = KinectSensor.KinectSensors.FirstOrDefault(x => x.Status == KinectStatus.Connected);
            brushes = new Brush[] { Brushes.Green, Brushes.Blue, Brushes.Gray, Brushes.Yellow, Brushes.Red };
            timer.Interval = TimeSpan.FromSeconds(2.0);
            timer.Tick += new EventHandler(timer_Tick);
            timer.Start();
        }

        void timer_Tick(object sender, EventArgs e)
        {
            for (int i = 0; i < GameCanvas.Children.Count; i++)
            {
                if (Canvas.GetTop(GameCanvas.Children[i])>GameCanvas.Height)
                {
                    GameCanvas.Children.RemoveAt(i);
                }
            }
            //新建一个ellipse控件
            Ellipse ellipse = new Ellipse();
            ellipse = NewEllipse(brushes[rand.Next(5)], 40, 40);
            Canvas.SetLeft(ellipse, rand.Next((int)GameCanvas.Width - 20));
            Canvas.SetTop(ellipse, 0);
            GameCanvas.Children.Add(ellipse);
            //Canvas上所有的Label控件下移40
            foreach (Ellipse item in GameCanvas.Children)
            {
                Canvas.SetTop(item, Canvas.GetTop(item) + 80);
            }
        }

        public KinectSensor KinectDevice
        {
            get { return this.kinectDevice; }
            set
            {
                if (this.kinectDevice != value)
                {
                    //Uninitialize
                    if (this.kinectDevice != null)
                    {
                        this.kinectDevice.Stop();
                        this.KinectDevice.ColorFrameReady -= KinectDevice_ColorFrameReady;
                        this.kinectDevice.SkeletonFrameReady -= KinectDevice_SkeletonFrameReady;
                        SkeletonViewerElement.KinectDevice = null;
                        this.frameSkeletons = null;
                        this.kinectDevice.SkeletonStream.Disable();
                    }

                    this.kinectDevice = value;

                    //Initialize
                    if (this.kinectDevice != null)
                    {
                        if (this.kinectDevice.Status == KinectStatus.Connected)
                        {
                            this.kinectDevice.ColorStream.Enable();
                            this.kinectDevice.SkeletonStream.Enable();
                            this.kinectDevice.DepthStream.Enable(DepthImageFormat.Resolution320x240Fps30);
                            this.frameSkeletons = new Skeleton[this.kinectDevice.SkeletonStream.FrameSkeletonArrayLength];
                            SkeletonViewerElement.KinectDevice = this.KinectDevice;
                            this.kinectDevice.Start();
                            this.KinectDevice.ColorFrameReady += KinectDevice_ColorFrameReady;
                            this.kinectDevice.SkeletonFrameReady += KinectDevice_SkeletonFrameReady;
                        }
                    }
                }
            }
        }

        void KinectDevice_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
        {
           using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
           {
               if (colorFrame == null)
               {
                   return;
               }
               byte[] pixels = new byte[colorFrame.PixelDataLength];
               colorFrame.CopyPixelDataTo(pixels);
               int stride = colorFrame.Width * 4;
               PeopleShow.Source = BitmapSource.Create(colorFrame.Width, colorFrame.Height, 96, 96, PixelFormats.Bgr32, null, pixels, stride);
           }
        }

        private void KinectDevice_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            using (SkeletonFrame frame = e.OpenSkeletonFrame())
            {
                if (frame == null)
                {
                    return;
                }
                else
                {
                    frame.CopySkeletonDataTo(frameSkeletons);
                    Skeleton skeleton = GetPrimarySkeleton(this.frameSkeletons);
                    if (skeleton != null)
                    {
                        TrackJoint(skeleton.Joints[JointType.HandRight]);
                    }
                }
            }
        }

        private void TrackJoint(Joint joint)
        {
            if (joint.TrackingState != JointTrackingState.Tracked)
            {
                return;
            }
            else
            {
                Point jointPoint = GetJointPoint(joint);
                if (GameCanvas.Children.Count > 0)
                {
                    foreach (Ellipse item in GameCanvas.Children)
                    {
                        if (HitTest(joint, item))
                        {
                            item.Visibility = Visibility.Collapsed;
                            GameCanvas.Children.Remove(item);
                            return;
                        }
                    }
                }
            }
        }

        private bool HitTest(Joint joint, UIElement target)
        {
            return (GetHitTarget(joint, target) != null);
        }

        private IInputElement GetHitTarget(Joint joint, UIElement target)
        {
            Point targetPoint = LayoutRoot.TranslatePoint(GetJointPoint(joint), target);
            return target.InputHitTest(targetPoint);
        }


        private Point GetJointPoint(Joint joint)
        {
            DepthImagePoint point = this.KinectDevice.MapSkeletonPointToDepth(joint.Position, this.KinectDevice.DepthStream.Format);
            point.X *= (int)this.GameCanvas.ActualWidth / KinectDevice.DepthStream.FrameWidth;
            point.Y *= (int)this.GameCanvas.ActualHeight / KinectDevice.DepthStream.FrameHeight;
            return new Point(point.X, point.Y + 200);
        }

        private static Skeleton GetPrimarySkeleton(Skeleton[] skeletons)
        {
            Skeleton skeleton = null;
            if (skeletons != null)
            {
                //查找最近的游戏者
                for (int i = 0; i < skeletons.Length; i++)
                {
                    if (skeletons[i].TrackingState == SkeletonTrackingState.Tracked)
                    {
                        if (skeleton == null)
                        {
                            skeleton = skeletons[i];
                        }
                        else
                        {
                            if (skeleton.Position.Z > skeletons[i].Position.Z)
                            {
                                skeleton = skeletons[i];
                            }
                        }
                    }
                }
            }
            return skeleton;
        }

        void KinectSensors_StatusChanged(object sender, StatusChangedEventArgs e)
        {
            switch (e.Status)
            {
                case KinectStatus.Initializing:
                case KinectStatus.Connected:
                case KinectStatus.NotPowered:
                case KinectStatus.NotReady:
                case KinectStatus.DeviceNotGenuine:
                    this.KinectDevice = e.Sensor;
                    break;
                case KinectStatus.Disconnected:
                    //TODO: Give the user feedback to plug-in a Kinect device.                    
                    this.KinectDevice = null;
                    break;
                default:
                    //TODO: Show an error state
                    break;
            }
        }

        private Ellipse NewEllipse(Brush brush, int width, int height)
        {
            Ellipse ellipse = new Ellipse();
            ellipse.Fill = brush;
            ellipse.Width = width;
            ellipse.Height = height;
            return ellipse;
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            timer.Stop();
            GameCanvas.Children.Clear();
        }
    }
}
